home *** CD-ROM | disk | FTP | other *** search
/ Language/OS - Multiplatform Resource Library / LANGUAGE OS.iso / escalant / escala21.lha / escalante2.1 / src / gm / PVGraphElement.h < prev    next >
C/C++ Source or Header  |  1993-07-15  |  14KB  |  568 lines

  1. //
  2. //    Copyright (C) 1993  Jeff McWhirter
  3. //
  4. #ifndef PVGraphElement_h
  5. #define PVGraphElement_h
  6.  
  7. #include    "EscalanteGlobal.h"
  8. #include    "GraphObject.h"
  9.  
  10. #include     "CommonElt.h" 
  11.  
  12. #include "ObjList.h"
  13.  
  14. class Class;
  15.  
  16. //class defs
  17. class PVRelation;
  18. class PVGraphElement;
  19.  
  20.  
  21.  
  22.  
  23. void WriteOutVSet(OStream & o);
  24. void ReadInVSet(IStream & o);
  25. extern bool gVSetIO;
  26. extern ObjList * gVProtoList;
  27.  
  28.  
  29. void SetCurrentVGraphElementSet(Set *s);
  30. Set * GetVGraphElementSet();
  31. void KillVGraphElements();
  32.  
  33.  
  34. Set * GetVDieSet();
  35.  
  36.  
  37. void SetCurrentVDieSet(Set * s);
  38.  
  39.  
  40. void InVDie(bool f);
  41. void StartVDie();
  42. void EndVDie();
  43.  
  44.  
  45.  
  46.  
  47. #define VITERDEP(element,ename,rname,dir,dep,deptype) {\
  48.     Iter eltloopiter((element)->GetRelations(dir));\
  49.     while(rname=(VRelation*)eltloopiter()) \
  50.         if(rname->GetEventDep(dep,deptype)){\
  51.             ename = (VGraphElement*)rname->GetOtherElement((element));
  52.  
  53. #define ENDVITERDEP }}
  54.  
  55.  
  56.  
  57.  
  58. enum PVGraphElementFlags{
  59.     ePVGEPropagating =     BIT(eGOLast+1),
  60.      ePVGECopied =        BIT(eGOLast+2),
  61.     ePVAdding =          BIT(eGOLast+3),
  62.     ePVOkToWriteOut =      BIT(eGOLast+4),
  63.     ePVOkToWriteOut2 =      BIT(eGOLast+5),
  64.     ePVGraphElementLast =    eGOLast+5
  65. };
  66.  
  67.  
  68.  
  69. //Propagation stuff
  70. typedef bool (*VPropFunc)(PVGraphElement*root,
  71.               PVRelation* rel, PVGraphElement* target,
  72.               void * data,
  73.               int hops ,
  74.               bool & b
  75.               );
  76.  
  77. typedef bool (*VPathFunc)(PVGraphElement*root,
  78.               PVRelation* rel, PVGraphElement* target,
  79.               void * data, int hops
  80.               );
  81.  
  82. typedef bool (*PVRelationOKFunc)(PVRelation*,void* );
  83.  
  84.  
  85.  
  86. #define PVGraphElement_BASE GraphObject
  87.  
  88. //
  89. //The following objects are group objects and are used to group a set
  90. //of incident relations or the connected elements of incident relations.
  91. //The OkToAdd Objects are used to determine if it is ok to add and element 
  92. //to a group. The OkToAdd class determines whether we are grouoing input or
  93. //output relations. The RelXElt class  decides based on the  type of 
  94. //relation and element.
  95. //
  96. //The group objects take use an  OkToAdd object to determine when an element
  97. //should be added to a group.
  98. //The      Group::relProto and Group::firstProto attributes are ptrs to relations.
  99. //The firstProto is used to add a relation between the element and the first element
  100. //in the group. The relProto is used to add relations between each successive element
  101. //in the group 
  102. //
  103. //The RelGroup groups incident relations the EltGroup groups the other elements
  104. //of incident relations
  105. //
  106.  
  107.  
  108. #ifdef USEGROUP
  109.  
  110.  
  111. class VOkToAdd: public Object{
  112. public:
  113. RDir dir;
  114. MetaDef(VOkToAdd);
  115. VOkToAdd(RDir d = eInOut){dir = d;}
  116. virtual bool InRelationOk(PVRelation *){
  117.     return (dir== eIn || dir == eInOut);
  118. }
  119. virtual bool OutRelationOk(PVRelation *){
  120.     return (dir== eOut || dir == eInOut);
  121. }
  122.  
  123. virtual bool HeadOk(PVGraphElement *,PVRelation *){
  124.     return (dir== eOut || dir == eInOut);
  125. }
  126.  
  127. virtual bool TailOk(PVGraphElement *,PVRelation *){
  128.     return (dir== eIn || dir == eInOut);
  129. }
  130.  
  131. OStream& PrintOn(OStream&);
  132. IStream& ReadFrom(IStream&);
  133. };
  134.  
  135.  
  136.  
  137.  
  138. class VRelXElt: public VOkToAdd{
  139. public:
  140. class Class* relc;
  141. class Class* eltc;
  142. MetaDef(VRelXElt);
  143. VRelXElt(Class * r,Class * e=0,RDir dir = eInOut):VOkToAdd(dir){
  144.     relc =r; eltc=e;
  145. }
  146. bool InRelationOk(PVRelation * );
  147. bool OutRelationOk(PVRelation *);
  148. bool HeadOk(PVGraphElement * ,PVRelation * );
  149. bool TailOk(PVGraphElement * ,PVRelation * );
  150. OStream& PrintOn(OStream&);
  151. IStream& ReadFrom(IStream&);
  152. };
  153.  
  154.  
  155.  
  156.  
  157.  
  158.  
  159. enum VGroupFlags{
  160.     eVKillRel = BIT(eGOLast+1),    
  161.     eVGroupLast = eGOLast+1};
  162.  
  163. class VGroup: public Object{
  164. public:
  165. int id;
  166. VOkToAdd * criteria;
  167. PVGraphElement * theelt;
  168. PVRelation     * relProto;
  169. PVRelation     * firstProto;
  170. ObjList* elts;
  171.  
  172. MetaDef(VGroup);
  173. void  InitClone(){elts=0;}
  174. VGroup(PVGraphElement * telt,PVRelation * proto,VOkToAdd * crit=0,PVRelation     * fp=0){
  175.     theelt= telt;relProto = proto;criteria = crit;elts=0; firstProto=fp;
  176. }
  177. ~VGroup();
  178. void DoObserve(int id, int part, void *d , Object *op);
  179. int GetId(){return id;}
  180. void SetId(int i){id =i;}
  181. virtual void AddElement(PVGraphElement*);
  182. virtual void RemoveElement(PVGraphElement * );
  183. void SetElement(PVGraphElement * elt){theelt = elt;}
  184. virtual void AddedInRelation(PVRelation * ){}
  185. virtual void RemovedInRelation(PVRelation * ){}
  186. virtual void AddedOutRelation(PVRelation * ){}
  187. virtual void RemovedOutRelation(PVRelation *){}
  188. virtual void NewTail(PVRelation * ,PVGraphElement* ,PVGraphElement*){}
  189. virtual void NewHead(PVRelation * ,PVGraphElement*,PVGraphElement*  ){}
  190. void Connect(PVGraphElement * e1,PVGraphElement * e2);
  191. OStream& PrintOn(OStream&);
  192. IStream& ReadFrom(IStream&);
  193. };
  194.  
  195.  
  196. class VRelGroup: public VGroup{
  197. public:
  198. MetaDef(VRelGroup);
  199. VRelGroup(class PVGraphElement * telt,PVRelation * proto,class VOkToAdd * cl,PVRelation* firstProto =0):
  200.     VGroup(telt,proto,cl,firstProto){}
  201. void RemovedInRelation(PVRelation * r){RemoveElement((PVGraphElement*)r );}
  202. void RemovedOutRelation(PVRelation * r){RemoveElement((PVGraphElement*)r);}
  203. void AddedRelation(PVRelation * r,RDir dir);
  204. void AddedInRelation(PVRelation * r){AddedRelation(r,eIn);}
  205. void AddedOutRelation(PVRelation * r){AddedRelation(r,eOut);}
  206. };
  207.  
  208.  
  209.  
  210. class VEltGroup: public VGroup{
  211. public:
  212. MetaDef(VEltGroup);
  213. VEltGroup(class PVGraphElement * telt,PVRelation * proto,class VOkToAdd  * cl,PVRelation* firstProto=0):
  214.     VGroup(telt,proto,cl,firstProto){}
  215. void RemovedInRelation(PVRelation * r);
  216. void RemovedOutRelation(PVRelation * r);
  217. void AddedInRelation(PVRelation * r);
  218. void AddedOutRelation(PVRelation * r);
  219. void NewElt(RDir dir,PVRelation *r ,PVGraphElement* newtl,PVGraphElement* oldtl =0);
  220. void NewTail(PVRelation *r ,PVGraphElement* newtl,PVGraphElement* oldtl =0){
  221. NewElt(eIn,r,newtl,oldtl);
  222. }
  223. void NewHead(PVRelation *r ,PVGraphElement* newhd,PVGraphElement* oldhd =0 ){
  224. NewElt(eOut,r,newhd,oldhd);
  225. }
  226. };
  227.  
  228.  
  229. #endif  USEGROUP
  230.  
  231.  
  232. class PVGraphElement: public GraphObject{
  233. public:
  234.  
  235. //
  236. //A list of prototypes for this element. Used in the EscalanteView palette and
  237. //for adding elements and finding default relations
  238. // 
  239. ObjList * protos;
  240.  
  241. //
  242. //The incoming and outgoing relations. An  InRel  is one in which this
  243. //element is the hd of the relations. OutRel -> this element is the tail
  244. //
  245. ObjList * InRels;
  246. ObjList * OutRels;
  247.  
  248. //
  249. //Used in event propagation
  250. //
  251. long int  eventMask;
  252. long int  affectedByEvents;
  253.  
  254.  
  255.  
  256. char * name;
  257.  
  258.  
  259.  
  260.  
  261. MetaDef(PVGraphElement);
  262. virtual  PVRelation * GetDefaultMemberOf(){return 0;}
  263.  
  264. PVGraphElement();
  265. ~PVGraphElement();
  266.  
  267.  
  268. void InitClone();
  269.  
  270.  
  271. #ifdef USEGROUP
  272. //
  273. //Group stuff 
  274. //
  275. ObjList * groups;
  276. void AddGroup(VGroup * g){
  277.     if(groups == 0) groups = new ObjList(); 
  278.     groups->Add(g);
  279.     g->SetElement(this);
  280. }
  281. VGroup * GetGroupWithId(int i);
  282. #endif USEGROUP
  283.  
  284. virtual void AddGroupRelation(PVRelation * r);
  285.  
  286.  
  287. virtual char * GetDescription(){return 0;}
  288.  
  289. bool  GetAdding(){return TestFlag(ePVAdding);}
  290. virtual void SetAdding(bool b){SetFlag(ePVAdding,b);}
  291.  
  292.  
  293. void SetName(char * nl){
  294.     strreplace(&name,nl);
  295.     SAC(PVGraphElement,name);
  296. }
  297. char * GetName(){return name;}
  298.  
  299.  
  300.  
  301. void * DoEvent2(Events event, PVGraphElement * elt, void * data, ObjList * list   );
  302. virtual void *DoEvent(Events event, PVGraphElement * elt =0, void * data=0);
  303.  
  304. bool DoneEvent(Events event) {return TestMask(eventMask,event);}
  305. void SetEvent(Events event) {SetMask(eventMask,event);}
  306.  
  307.  
  308. void ClearEvent(Events event = eEventNull) {
  309.     if(event == eEventNull) eventMask= 0;
  310.     else     ResetMask(eventMask,event);
  311. }
  312.  
  313.  
  314.  
  315. void * PropagateEvent(Events event,Events notevents, PVGraphElement * elt =0, void * data =0,ObjList * list = 0);
  316.  
  317. virtual void * PropagateEvent2(Events event,Events notevents, PVGraphElement * elt =0, void * data =0,ObjList * list = 0);
  318.  
  319. void * PropagateEvent(Events event, PVGraphElement * elt, void * data =0,ObjList * list = 0){
  320. return PropagateEvent( event,(Events)0,elt, data , list );
  321. }
  322.  
  323.  
  324. void*        GetAttribute(int aid,DataType & type);
  325. void        ChangeAttribute(int aid, void * data, DataType type);
  326. void        SendAttributeChange(int aid, void * data=0,DataType type = eNullAttrType);
  327.  
  328.  
  329. void NewProtos(){protos = new ObjList();}
  330. void AddPrototype(PVGraphElement *e){if(!protos) NewProtos();protos->Add((Object*)e);}
  331. PVGraphElement*  GetPrototype(PVGraphElement *e){return (protos? 
  332.                                ((protos->Contains((Object*)e))? e:0):
  333.                                0);}
  334. PVGraphElement*  GetPrototypeOfClass(class Class * c);
  335. ObjList * GetPrototypes(){return protos;}
  336.  
  337. virtual bool AddOnlyIfHaveProto(){return FALSE;}
  338. virtual bool AddOnlyIfHaveDflt(){return FALSE;}
  339. virtual bool AddOnCloning(){return TRUE;}
  340.  
  341.  
  342. bool OkToWriteOut(){ 
  343.     return (IfFalseDontWriteOutOriginal() &&
  344.         IfFalseDontWriteOutClone()    &&
  345.         !IsDead());
  346.          }
  347.  
  348. bool IfFalseDontWriteOutOriginal(){return TestFlag(ePVOkToWriteOut);}
  349. void IfFalseDontWriteOutOriginal(bool f){SetFlag(ePVOkToWriteOut,f);}
  350.  
  351.  
  352. bool IfFalseDontWriteOutClone(){return TestFlag(ePVOkToWriteOut2);}
  353. void IfFalseDontWriteOutClone(bool f){SetFlag(ePVOkToWriteOut2,f);}
  354.  
  355.  
  356.  
  357. void Die(); 
  358. void SetDead(bool f);
  359. virtual void MS_Die(){} 
  360.  
  361.  
  362.  
  363. bool Copied(){return TestFlag(ePVGECopied);} 
  364. void Copied(bool f){SetFlag(ePVGECopied,f);}
  365. PVGraphElement *  Copy();
  366.  
  367.  
  368. //
  369. //Function propagation stuff
  370. //
  371. //
  372. //You can give an element a function to propagate along its incident 
  373. //relations. The first PFunc lets you specify a function (func)
  374. //and data to pass to the function (funcdata)
  375. //the type of relations and elements to propagate along (relc,eltc), 
  376. //how many hops (maxhops) to go, and the direction of propagation.
  377. //The function takes the following parameters:
  378. //typedef bool (*VPropFunc)(PVGraphElement*root,
  379. //              PVRelation* rel, PVGraphElement* target,
  380. //              void * data,
  381. //              int hops ,
  382. //              bool & b
  383. //              );
  384. //Where root is the original element called. rel and target are 
  385. //the relation and the target element of the relation,
  386. //hops is the hops so far 
  387. //b if FALSE then we exit the entire propagation
  388. //If the function returns FALSE then we don't  continue
  389. //propagation with the target 
  390.  
  391. //The second PFunc method lets you specify a function (path) and
  392. //data to pass to that functin (pathdata). This function decides
  393. //which is an ok path to go on.
  394. //
  395.  
  396. bool Propagating(){return TestFlag(ePVGEPropagating);}
  397. void Propagating(bool f){SetFlag(ePVGEPropagating,f);}
  398.  
  399. bool PFunc(VPropFunc func,
  400.        void * funcdata, 
  401.        class  Class* relc,
  402.        class  Class* eltc,
  403.        int maxhops = MAXINT, 
  404.        RDir dir= eInOut);
  405.  
  406.  
  407. bool PFunc( VPropFunc func ,
  408.        void * funcdata, 
  409.        int maxhops  = MAXINT, 
  410.        RDir dir= eInOut,  
  411.        VPathFunc path =0 ,
  412.        void * pathdata = 0,
  413.        ObjList * l =0,
  414.        int hopssofar = 0);
  415.  
  416.  
  417. OStream& PrintOn(OStream&);
  418. IStream& ReadFrom(IStream&);
  419.  
  420.  
  421. //
  422. //These can get called when looking for and element to set the tl or head 
  423. //of a relation (in EscalanteView)
  424. //
  425. virtual    bool    OkToAddInRelation(PVRelation * r){return TRUE;}
  426. virtual    bool    OkToAddOutRelation(PVRelation * r){return TRUE;}
  427.  
  428.  
  429. //
  430. //These methods move in/out relation ptrs to the front/back of the list
  431. //
  432. void MoveRelation(PVRelation * r, RDir dir,bool tofront= TRUE);
  433. void InRelationToFront(PVRelation * r){MoveRelation(r,eIn,TRUE);}
  434. void InRelationToBack(PVRelation * r){MoveRelation(r,eIn,FALSE);}
  435. void OutRelationToFront(PVRelation * r){MoveRelation(r,eOut,TRUE);}
  436. void OutRelationToBack(PVRelation * r){MoveRelation(r,eOut,FALSE);}
  437.  
  438.  
  439.  
  440. //
  441. //These  methods return the predecessor/successor (e.g. tl of in rel, hd of out rel)
  442. //for relations of type relClass and pred/succ of type eltClass
  443. //rIsKindOf and eIsKindOf are flags that signal how to check - using IsKindOf or IsA
  444. //
  445. PVGraphElement * Pred(class Class *relClass=0,
  446.                class Class * eltClass=0,
  447.                bool rIsKindOf = TRUE,
  448.                bool eIsKindOf  = TRUE);
  449.  
  450. PVGraphElement * Succ(class Class *relClass=0,
  451.                class Class * eltClass=0,
  452.                bool rIsKindOf = TRUE,
  453.                bool eIsKindOf  = TRUE);
  454.  
  455.  
  456. //
  457. //These methods are just like the ones above except return the relation
  458. //
  459.  
  460. PVRelation * RelPred(class Class *relClass=0,
  461.               class Class * eltClass=0,
  462.               bool rIsKindOf = TRUE,
  463.               bool eIsKindOf  = TRUE);
  464.  
  465. PVRelation * RelSucc(class Class *relClass=0,
  466.               class Class * eltClass=0,
  467.               bool rIsKindOf = TRUE,
  468.               bool eIsKindOf  = TRUE);
  469.  
  470.  
  471. void Pred(Class *relClass,
  472.       Class * eltClass,
  473.       PVRelation*&,
  474.       PVGraphElement*&,
  475.       bool rIsKindOf,
  476.       bool eIsKindOf);
  477.  
  478. void Succ(Class *relClass,
  479.       Class * eltClass,
  480.       PVRelation*&,
  481.       PVGraphElement*&,
  482.       bool rIsKindOf,
  483.       bool eIsKindOf);
  484.  
  485.  
  486.  
  487.  
  488. //
  489. //Incident relation stuff
  490. //
  491.  
  492.  
  493.  
  494. //
  495. //Getting new relations and tails/heads
  496. //
  497. virtual void AddInRelation(PVRelation *r);
  498. virtual void RemoveInRelation(PVRelation *r);
  499. virtual void AddOutRelation(PVRelation *r);
  500. virtual void RemoveOutRelation(PVRelation *r);
  501. virtual void NewTail(PVRelation * r, PVGraphElement * newtl=0,PVGraphElement* oldtl =0);
  502. virtual void NewHead(PVRelation * r, PVGraphElement * newhd=0,PVGraphElement* oldhd =0);
  503.  
  504.  
  505. //
  506. //Return the correct list of   relations
  507. //
  508. ObjList * GetRelations(RDir dir = eIn){return (dir == eIn ? InRels : OutRels);}
  509.  
  510.  
  511. //
  512. //This find a relation of type c with other element == elt
  513. //
  514. PVRelation * GetRelation(PVGraphElement*elt ,
  515.               RDir dir = eIn,
  516.               class Class * c = 0,
  517.               bool rIsKindOf =TRUE);
  518.  
  519. //
  520. //This finds the incident relations with a certain dependency set
  521. //
  522. void GetRelsWithDep(ObjList & l, Events events, DepTypes type,RDir dir);
  523.  
  524.  
  525. //
  526. //This gets called by an incident relation when some event dependency changes
  527. //
  528. virtual void DepChange(Events event, DepTypes type){}
  529.  
  530.  
  531.  
  532.  
  533. //
  534. //This searches through the protos list trying to find some  relation of
  535. //type rc with tail and head of the same type of the tl and hd args.
  536. //
  537. PVRelation * GetDefaultRelation(PVGraphElement * tl,
  538.                  PVGraphElement * hd,
  539.                  class Class * rclass = 0 );
  540.  
  541.  
  542. //
  543. //These methods are used to add an element to this element.
  544. //This adding is in effect adding a new relation between this element
  545. //and the new element
  546. //
  547. void AddElement(PVGraphElement * elt, PVRelation * rel =0 );
  548. void AddElements(Set *s);
  549.  
  550.  
  551. };
  552.  
  553.  
  554.  
  555.  
  556. #endif PVGraphElement_h
  557.  
  558.  
  559.  
  560.  
  561.  
  562.  
  563.  
  564.  
  565.  
  566.  
  567.  
  568.